package ch.il07.converter.persistance.tests;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.List;

import org.junit.Before;
import org.junit.Test;

import ch.il07.converter.persistence.Persistence;
import ch.il07.converter.persistence.PersistenceHelper;
import ch.il07.converter.persistence.entities.Measurand;
import ch.il07.converter.persistence.entities.Unit;
import ch.il07.converter.persistence.entities.User;
import ch.il07.converter.persistence.exceptions.AlreadyDefinedException;
import ch.il07.converter.persistence.exceptions.PersistenceException;
import ch.il07.converter.persistence.exceptions.UserAlreadyExistsException;
import ch.il07.utils.RandomHelper;

public class DeleteMeasurand {

	private Persistence persistence;

	@Before
	public void setUp() {
		try {
			persistence = PersistenceHelper.getPersistence();
		} catch (PersistenceException e) {
			fail(e.getMessage());
		}
	}

	@Test
	public void deletePublicMeasurandString() {
		String mName = RandomHelper.randString();
		Measurand m = new Measurand(mName, new Unit(RandomHelper.randString(),
				1D));

		{ // add
			try {
				persistence.addMeasurand(m, null);
			} catch (AlreadyDefinedException e) {
				fail(e.getMessage());
				e.printStackTrace();
			} catch (PersistenceException e) {
				fail(e.getMessage());
				e.printStackTrace();
			}
		}

		{ // check whether it exists
			try {
				List<Measurand> measurands = persistence.getMeasurands();

				boolean measurandIsAvailable = false;
				for (Measurand measurand : measurands) {
					if (measurand.getName().equals(mName)) {
						m = measurand;
						measurandIsAvailable = true;
						break;
					}
				}
				assertTrue("measurand '" + mName + "' should exist in db",
						measurandIsAvailable);
			} catch (PersistenceException e) {
				fail(e.getMessage());
			}
		}

		{ // delete
			try {
				persistence.deleteMeasurand(m, null);
			} catch (PersistenceException e) {
				fail(e.getMessage());
			}
		}
	}

	@Test
	public void deletePrivateMeasurandString() {
		String mName = RandomHelper.randString();
		Measurand m = new Measurand(mName, new Unit(RandomHelper.randString(),
				1D));

		String username = RandomHelper.randString();
		User u = new User(username, username, RandomHelper.getEmail(username));

		{ // create user
			try {
				persistence.addUser(u.getUsername(), u.getEmail(), u.getPassword(),
						u.getAccessLevel());
				assertNotNull("user '" + u.getUsername()
						+ "' should have been created",
						persistence.getUser(u.getUsername(), u.getPassword()));
			} catch (UserAlreadyExistsException e) {
				fail(e.getMessage());
			} catch (PersistenceException e) {
				fail(e.getMessage());
			}
		}

		{ // add
			try {
				persistence.addMeasurand(m, u.getUsername());
			} catch (AlreadyDefinedException e) {
				fail(e.getMessage());
			} catch (PersistenceException e) {
				fail(e.getMessage());
			}
		}

		{ // check whether it exists
			try {
				List<Measurand> measurands = persistence.getMeasurands(u.getUsername());
				boolean measurandIsAvailable = false;
				for (Measurand measurand : measurands) {
					if (measurand.getName().equals(mName)) {
						m = measurand;
						measurandIsAvailable = true;
						break;
					}
				}
				assertTrue("measurand '" + mName + "' should exist in db",
						measurandIsAvailable);
			} catch (PersistenceException e) {
				fail(e.getMessage());
			}
		}

		{ // delete
			try {
				persistence.deleteMeasurand(m, u.getUsername());
			} catch (PersistenceException e) {
				fail(e.getMessage());
			}
		}

		{ // make sure it's been deleted
			try {
				List<Measurand> measurands = persistence.getMeasurands();
				assertFalse("measurand '" + mName + "' should be removed",
						measurands.contains(m));
			} catch (PersistenceException e) {
				fail(e.getMessage());
			}

		}
	}
}
